using Hylasoft.Opc.Da;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;

namespace Test
{
    partial class Program
    {
        static void TestBeanstalk()
        {
            using (var qu = new Droog.Beanstalk.Client.BeanstalkClient("127.0.0.1", 11300))
            {
                qu.CurrentTube = "test";
                var res = qu.Put(110, new TimeSpan(0, 0, 10), new TimeSpan(0, 10, 0), new MemoryStream(Encoding.ASCII.GetBytes("Hello, world!")), 13);
                qu.CurrentTube = "test1";
                res = qu.Put(110, new TimeSpan(0, 0, 10), new TimeSpan(0, 10, 0), new MemoryStream(Encoding.ASCII.GetBytes("Hello, man!")), 11);

                foreach (string tb in qu.GetTubes())
                {
                    var status = qu.GetTubeStats(tb);
                    Console.WriteLine("{0}:{1},{2}", status.Name, status.TotalJobs, status.CurrentReadyJobs);
                }
            }

            using (var qu = new Droog.Beanstalk.Client.BeanstalkClient("127.0.0.1", 11300))
            {
                Droog.Beanstalk.Client.Job job = null;
                byte[] buf = null;
                TimeSpan ts = new TimeSpan(0, 0, 10);

                qu.WatchedTubes.Add("test1");

                foreach (string tb in qu.GetTubes())
                {
                    var status = qu.GetTubeStats(tb);
                    Console.WriteLine("{0}:{1},{2}", status.Name, status.TotalJobs, status.CurrentReadyJobs);
                }

                while (true)
                {
                    try
                    {
                        job = qu.Reserve(ts);
                        qu.Delete(job.Id);
                        buf = new byte[job.DataLength];
                        job.Data.Read(buf, 0, buf.Length);
                        Console.WriteLine(Encoding.ASCII.GetString(buf, 0, buf.Length));
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 请求选项，可进行位运算
        /// </summary>
        [Flags]
        public enum RequestFlag
        {
            /// <summary>
            /// 不分包并且不需要应答
            /// </summary>
            SinglePartAndNoAnswer = 0,
            /// <summary>
            /// 需要应答
            /// </summary>
            Answer = 1,
            /// <summary>
            /// 分包传输
            /// </summary>
            MultiPart = 2
        }

        static void TestEnum()
        {
            log4net.ILog logger = log4net.LogManager.GetLogger("main");

            RequestFlag flag = (RequestFlag)3;
            logger.InfoFormat("3:{0}", flag);
        }

        static void TestOpc()
        {
            using (var client = new DaClient(new Uri("opcda://127.0.0.1/Knight.OPC.Server.Demo")))
            {
                client.Connect();

                while (client.Status == Hylasoft.Opc.Common.OpcStatus.Connected)
                {
                    var tags = ExploreNodes(client, client.RootNode.Tag);
                    foreach (var tag in tags)
                    {
                        var tp = client.GetDataType(tag);
                        //var ret = client.Read<object>(tag);

                        var ret = client.ReadAsync<object>(tag);
                        Console.WriteLine("{0}:{1},{2}", tag, ret.Result, tp);
                    }

                    Thread.Sleep(1000);
                }

                //if (client.Status != Hylasoft.Opc.Common.OpcStatus.Connected)
                //    return;

                //var tags = ExploreNodes(client, client.RootNode.Tag);
                //foreach (var tag in tags)
                //{
                //    client.Monitor<object>(tag, (val, un) =>
                //    {
                //        Console.WriteLine("{0}:{1}", tag, val);
                //        //un();
                //    });
                //}
            }
        }

        static IEnumerable<string> ExploreNodes(DaClient client, string tag)
        {
            var nodes = client.ExploreFolder(tag);
            if (nodes == null || nodes.Count() == 0)
                return new string[] { tag };

            var tags = nodes.Select<DaNode, string>((node) => node.Tag);
            var lst = new List<string>();
            foreach (var tag1 in tags)
            {
                var subs = ExploreNodes(client, tag1);
                lst.AddRange(subs);
            }

            return lst;
        }

        static void Main(string[] args)
        {
            log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));
            //log4net.ILog logger = log4net.LogManager.GetLogger("main");

            //TestBeanstalk();

            //while (true)
            //{
            //    logger.InfoFormat("当前时间：{0}", DateTime.Now);
            //    Thread.Sleep(10000);
            //}

            //TestEnum();

            TestOpc();

            Console.ReadLine();
        }
    }
}